#-*-coding:utf-8-*-
'''
This module is used to test the other modules.
'''
import random
from fileoperate import FileOperate
from math import sqrt,log
from jpgmodule import myJpg
import Image
from LFSR import LFSR
class test:
    '''
    Test.
    '''
    def __init__(self):
        pass

    def GetTestMatrixData(self,row,col,xmin,mmax):
        '''
        Get the Test MatrixData.
        row refer to rows
        col refer to cols
        xmin refer to the small int
        '''
        content = [[0 for i in range(col)]for j in range(row)]  #construct the Matrix
        ntotal = random.randint(xmin,mmax) #the total
        alldata = range(ntotal)
        #random.shuffle(alldata)
        k = row*col - 1
        while alldata:
            pos = random.randint(0,k)       #get the random pos
            i = pos/col
            j = pos % col
            if content[i][j] == 0:
                content[i][j] = [alldata.pop(0)]
            else:
                content[i][j].append(alldata.pop(0))
        return content

    def mhtxt(self,filename):
        '''
        get mh.txt
        '''
        avf = open(filename,'rb')
        c = list()
        while True:
            k = avf.readline()
            if k:
                c.append(k.strip())
            else:
                break
        avf.close()
        c.sort()

        for i in range(len(c)):
            c[i] = c[i].replace(' ','\t')

        print c
        avf = open('outmh.txt','wb')
        avf.writelines(c)
        avf.flush()
        avf.close()

    def calchist(self,pathname):
        '''
        calc the keys in the file
        pathname is the absolute path of the file.
        '''
        fo = FileOperate()
        dt = fo.ReadAllBytes(pathname)
        keys = list(set(dt))         #get all the keys except flag'\0'
        x = list()
        for i in keys:
            x.append((ord(i),dt.count(i)))         #get the total of the characters
        return x
        
    def clacFre(self,infile,outfile):
        '''
        Get the pixels statistics.
        '''
        fo = FileOperate()
        c = fo.ReadAllBytes(infile)
        y = ''
        print len(c)
        for i in range(256):
            y += (str(c.count(chr(i))) + ' ')
        fo.WriteFileStr(outfile,y)
        print 'Done!'
        
    def InformationEntropy(self,infile):
        '''
        Calc the information entropy.
        '''
        fo = FileOperate()
        c = fo.ReadAllBytes(infile)
        lent = float(len(c))
        entr = 0
        for i in range(256):
            k = c.count(chr(i))
            if k != 0:
                entr += ((k / lent) * (log(lent / k) / log(2)))
        print 'Information Entropy:%f'%entr
        
    def FindDis(self,infi1,infi2):
        '''
        Get the difference.
        '''
        fo = FileOperate()
        infi1 = fo.ReadAllBytes(infi1)
        infi2 = fo.ReadAllBytes(infi2)
        k1 = len(infi1)
        k2 = len(infi2)
        print 'file1 length:'+str(k1)
        print 'file2 length:'+str(k2)
        
        l = min(k1,k2)
        print 'compare length:' + str(l)
        h = 0
        for i in range(l):
            if infi1[i] != infi2[2]:
                h += 1
        print 'Difference:' + str(h)
        print 'Percentate:' + str( float(h) / l)
        
    def CoRelation(self,infi,size,allpix = 5000):
        '''
        calculate the co-relationsh of a picture
        infi is the path of the file
        allpix is the total pixels to be calculated.
        '''
        fo = FileOperate()
        infi = fo.ReadAllBytes(infi)
        #vertical
        x = list()
        y = list()
        al = len(infi)
        pi = list()
        for i in range(allpix):
            h = random.randint(0,size[0] - 1)
            w = random.randint(0,size[1] - 1)
            while ((h,w) in pi) or (((h + 1) * size[1] + w) >= al):
                h = random.randint(0,size[0] - 1)
                w = random.randint(0,size[1] - 1)
            else:
                pi.append((h,w))
                x.append(ord(infi[h * size[1] + w]))
                y.append(ord(infi[(h + 1) * size[1] + w]))
        k = self.ClacEDCX(x,y)
        print 'Vertical:%f'%k        
        #Horizontal
        x = list()
        y = list()
        pi = list()
        for i in range(allpix):
            h = random.randint(0,size[0] - 1)
            w = random.randint(0,size[1] - 1)
            while ((h,w) in pi) or ((h * size[1] + w + 1) >= al):
                h = random.randint(0,size[0] - 1)
                w = random.randint(0,size[1] - 1)
            else:
                pi.append((h,w))
                x.append(ord(infi[h * size[1] + w]))
                y.append(ord(infi[h * size[1] + w + 1]))
        k = self.ClacEDCX(x,y)
        print 'Horizontal:%f'%k
        #diagonal
        x = list()
        y = list()
        pi = list()
        for i in range(allpix):
            h = random.randint(0,size[0] - 1)
            w = random.randint(0,size[1] - 1)
            l = random.choice([(1,1),(1,-1),(-1,1),(-1,-1)])
            while ((h,w) in pi) or (((h + l[0]) * size[1] + w + l[1]) >= al) or((h * size[1] + w) >= al):
                h = random.randint(0,size[0] - 1)
                w = random.randint(0,size[1] - 1)
            else:
                pi.append((h,w))
                x.append(ord(infi[h * size[1] + w]))
                y.append(ord(infi[(h + l[0]) * size[1] + l[1]]))
        k = self.ClacEDCX(x,y)
        print 'Diagonal:%f'%k
        
    def ClacEDCX(self,x,y,t = 5000.0):
        '''
        function
        '''
        print 'len(x):%d'%len(x)
        print 'len(y):%d'%len(y)
        Ex = reduce(lambda i,j:i + j,x,0)
        Ex /= t
        Dx = [(i - Ex)**2 for i in x]
        Dx = reduce(lambda i,j:i + j,Dx,0)
        Dx /= t
        
        Ey = reduce(lambda i,j:i + j,y,0)
        Ey /= t
        Dy = [(i - Ey)**2 for i in y]
        Dy = reduce(lambda i,j:i + j,Dy,0)
        Dy /= t
        
        covxy = [(x[i] - Ex)*(y[i] - Ey) for i in range(int(t))]
        covxy = reduce(lambda i,j:i + j,covxy,0)
        covxy /= t
        
        return covxy / (sqrt(Dx) * sqrt(Dy))
        
    def ChangePixels(self,pathname,dstpn,pos):
        '''
        to change the pixels
        pathname is the absolute pathway of the file.
        num is the number of the pixels which need to be changed.
        '''
        myjpg = myJpg()
        c = Image.open(pathname)
        k = c.getdata()
        k = list(k)
        lent = len(k) 
        if k[pos[0] * c.size[1] + pos[1]] == 255:
            k[pos[0] * c.size[1] + pos[1]] -= 1
        else:
            k[pos[0] * c.size[1] + pos[1]] += 1
        myjpg.SaveLAs(dstpn,k,c.size)
        print 'Done!'
        #c.ChangePixels('E:\\workspace\\graduateprject\\module\\image-compress-encrypt\\res\\key\\couple.tiff','E:\\workspace\\graduateprject\\module\\image-compress-encrypt\\res\\key\\coupleNew.tiff',10)
    
    def getCpic(self,pathname,dstpn,size,num = 10):
        '''
        Get the change picture.
        '''
        pos = list()
        while len(pos) < num:
            x = random.randint(0,size[0] - 1)
            y = random.randint(0,size[1] - 1)
            if (x,y) not in pos:
                pos.append((x,y))
                ks = '%d_%d.tiff'%(x,y)
                self.ChangePixels(pathname,dstpn + ks,(x,y))    
    
    def CalcDif(self,pn1,pn2,num = 10):
        '''
        calculate the NPCR and UACI
        '''
        fo = FileOperate()
        c1 = fo.ReadAllBytes(pn1)
        c2 = fo.ReadAllBytes(pn2)
        #d = list()
        len1 = len(c1)
        len2 = len(c2)
        print 'Image1:%d'%len1
        print 'Image2:%d'%len2
        k = min(len1,len2)
        npcr = 0
        uaci = 0
        for i in range(k):
            if c1[i] == c2[i]:
                #d.append(0)
                npcr += 0
            else:
                #d.append(1)
                npcr += 1
            uaci += (abs(ord(c1[i]) - ord(c2[i])))
            
        print 'NPCR:%f'%(float(npcr)/k)
        print 'UACI:%f'%(float(uaci)/(k * 255))
        
    def RandomnessTestLFSR(self,infile,length=1000):
        '''
        test the randomness of the sequence
        '''
        fo = FileOperate()
        fo.OpenReadFile(infile)
        kstr = fo.ReadFileByBytes(length)
        initvalue = fo.BytesToBits(kstr)
        c = LFSR()
        c.main(0,[8 * length],initvalue)
        
        



